import wx
import wx.glcanvas
from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *
import Image
import sys,math,time


class reactor:
    def __init__(self):
        self.core = None
        self.backend = wx.PySimpleApp()
        self.mainframe = wx.Frame(None,-1,'3D Render Engine',wx.DefaultPosition,wx.Size(400,400))
        self.widget = myGLCanvas(self.backend,self.mainframe)
        self.factory = factory(self.mainframe)
        
    def run(self):
        self.mainframe.Show()
        self.backend.MainLoop()

class factory:
    def __init__(self,mainframe):
        self.mainframe = mainframe
    def setSize(self,size):
        self.mainframe.SetSize(size)
    def setTitle(self,text):
        self.mainframe.SetTitle(text)


class myGLCanvas(wx.glcanvas.GLCanvas):
    def __init__(self, app, parent):
        wx.glcanvas.GLCanvas.__init__(self, parent,-1)

        self.Bind(wx.EVT_PAINT,self.OnPaint)
        self.Bind(wx.EVT_IDLE, self.OnPaint)
        self.Bind(wx.EVT_KEY_DOWN,self.KeysDown)
        
        self.t0 = time.time()
        self.frames = 0
        self.app = app
        self.parent = parent
        self.InitGL()
        self.Show()
    
    def KeysDown(self,event):
        print event.GetKeyCode()
        if event.GetKeyCode() == 27:
            self.app.ExitMainLoop()
            self.app.Destroy()
            
    def OnPaint(self,event):
        self.SetCurrent()
        self.OnDraw()

    def OnDraw(self):
        (w,h) = self.parent.GetSize()
        glViewport(0, 0, w, h)
        
        glClearColor(0.0, 0.0, 1.0, 1.0)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        #glClearDepth(1.0)

        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(40, w/float(h or 1), 0.25, 100)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        gluLookAt(10,0,0,
                  0,0,0,
                  0,0,1)
        
        ## Render Geometry and Apply Loaded Texture
        glColor3f(1.0, 1.0, 1.0)
        
        glEnable(GL_TEXTURE_2D)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)
        glBindTexture(GL_TEXTURE_2D, self.texture)
        #print glGetIntegerv(GL_TEXTURE_BINDING_2D)
        #if not glIsTexture(self.texture):
        #    print "Error: texture not binded - Texture ID:",self.texture
        
        glBegin(GL_TRIANGLES)
        
        glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.000000, 1.000000, -1.000000 )
        glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.000000, -1.000000, -1.000000 )
        glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.000000, -1.000000, -1.000000 )
        glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.000000, -1.000000, -1.000000 )
        glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.000000, 1.000000, -1.000000 )
        glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.000000, 1.000000, -1.000000 )
        
        glEnd()
        
        glDisable(GL_TEXTURE_2D)
        
        self.SwapBuffers()
        errors = glGetError()
        while errors:
            print "OpenGL Error: %s"%errors
            errors = glGetError()
        
    
    def InitGL(self):
        
        (w,h) = self.parent.GetSize()
        
        glutInit(sys.argv)
        glViewport(0, 0, w, h)
        glClearColor(0.0, 0.0, 1.0, 1.0)
        glClearDepth(1.0)

        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(40.0, 1.0, 0.25, 200.0)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        gluLookAt(10,0,0,
                  0,0,0,
                  0,0,1)
        
        
        # Load Texture
        im = Image.open('t1.png')
        imageWidth = im.size[0]
        imageHeight = im.size[1]
        image = im.tostring("raw", "RGBX", 0, -1)
        self.texture = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D, self.texture)
        glPixelStorei(GL_UNPACK_ALIGNMENT,1)
        glTexImage2D(GL_TEXTURE_2D, 0, 3, imageWidth, imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,  image)
        
reactor().run()  
